package com.shareach.service.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import com.google.common.collect.Lists;
import com.mongodb.BasicDBObjectBuilder;
import com.shareach.common.BaseQueryOrder;
import com.shareach.common.BizCondition;
import com.shareach.dao.mongo.BizActivityDao;
import com.shareach.domain.BizActivityDomain;
import com.shareach.service.BizActivityService;
import com.shareach.service.exception.BaseService;
import com.shareach.util.Globals;
import com.shareach.util.ReflectionUtil;

/**
 * create time：2013-2-1 下午12:24:33
 * 
 * @author retryu
 * @since JDK 1.6
 * @version 1.0 description：
 */

@Service
public class BizActivityServiceImpl extends BaseService<BizActivityDomain> implements BizActivityService {

	@Autowired
	private BizActivityDao bizActivityDao;

	@Override
	public synchronized Long save(BizActivityDomain domain) {
		domain.setCreatTime(new Date());
		Long id = bizActivityDao.insert(domain);
		return id;
	}

	@Override
	public long saveOrUpdateBySid(BizActivityDomain domain) {
		BizActivityDomain activityQry = new BizActivityDomain();
		activityQry.setSid(domain.getSid());
		activityQry.setCity(domain.getCity());
		activityQry.setBankId(domain.getBankId());
		
		BizActivityDomain exists = findOne(activityQry);
		if (null != exists) {
			domain.setId(exists.getId());
			update(domain);
			return exists.getId();
		}
		
		return save(domain);
	}
	
	@Override
	public void del(BizActivityDomain domain) {
		if (domain.getId() == null)
			return;
		Query query = new Query();
		query.addCriteria(Criteria.where("_id").is(domain.getId()));
		bizActivityDao.delete(query, BizActivityDomain.class);
	}

	@Override
	public synchronized void update(BizActivityDomain domain) {
		if (domain.getId() == null)
			return;
		Update update = parseDomaintoUpdate(domain);

		if (update.getUpdateObject().toMap().size() > 0) {
			bizActivityDao.update(Criteria.where("_id").is(domain.getId()), update);
		}
	}

	@Override
	public synchronized void update(BizActivityDomain domain, BizCondition contion) {
		// handle parse conditon
		Query query = parseConditionToQuery(contion);
		// handle update condition...
		Update update = parseDomaintoUpdate(domain);

		// update discountWeeks if necessary
		Integer[] disCountWeeks = domain.getDiscountWeek();
		if (disCountWeeks != null && disCountWeeks.length > 0) {
			update.addToSet("discountWeeks", BasicDBObjectBuilder.start("$each", disCountWeeks).get());
		}
		// if update is empty will remove the mongo data
		if (update.getUpdateObject().toMap().size() != 0) {
			bizActivityDao.update(query, update);
		}
	}

	@Override
	public BizActivityDomain getById(Long id) {
		if (id == null)
			return null;
		Query query = new Query();
		query.addCriteria(Criteria.where("_id").is(id));
		BizActivityDomain activity = bizActivityDao.findOne(query);
		return activity;
	}

	@Override
	public List<BizActivityDomain> getList(BizActivityDomain domain) {
		Query query = parseDomaintoQuery(domain);

		List<BizActivityDomain> activitys = bizActivityDao.findList(query);
		return activitys;
	}

	@Override
	public List<BizActivityDomain> getList(BizCondition condition) {
		Query query = parseConditionToQuery(condition);
		List<BizActivityDomain> activitys = bizActivityDao.findList(query);
		return activitys;
	}

	@Override
	public Page<BizActivityDomain> getPageResult(BizActivityDomain domain, BaseQueryOrder order) {
		Map<Object, Object> domainMap = ReflectionUtil.parseDomaintoMap(domain);
		Query query = new Query();
		for (Entry<Object, Object> entry : domainMap.entrySet()) {
			if (entry.getKey().equals("title")) {
				query.addCriteria(Criteria.where((String) entry.getKey()).regex((String) entry.getValue()));
			} else if (entry.getKey().equals("updateTime")) {
				continue;
			} else {
				query.addCriteria(Criteria.where((String) entry.getKey()).is(entry.getValue()));
			}
		}
		
		if (null != domain.getId() && !domainMap.containsKey(domain.getId())) {
			query.addCriteria(Criteria.where("_id").is(domain.getId()));
		}
		
		Page<BizActivityDomain> domainPage = bizActivityDao.getPageResult(query, order);

		return domainPage;
	}

//	@Override
//	public void saveActivityImg(MultipartFile file, List<BizActivityDomain> activities, String path) {
//		try {
//			InputStream inputStream = file.getInputStream();
//
//			String suffix = "." + file.getContentType().split("/")[1];
//			String fileName = "" + System.currentTimeMillis() + suffix;
//			OutputStream outputStream = new FileOutputStream(path + "/" + fileName);
//			byte[] buffer = file.getBytes();
//			@SuppressWarnings("unused")
//			int bytesum = 0;
//			int byteread = 0;
//			while ((byteread = inputStream.read(buffer)) != -1) {
//				bytesum += byteread;
//				outputStream.write(buffer, 0, byteread);
//				outputStream.flush();
//			}
//			outputStream.close();
//			inputStream.close();
//			for (BizActivityDomain activity : activities) {
//				activity.setImg(fileName);
//				update(activity, new BizCondition().put("id", activity.getId()));
//			}
//		} catch (Exception e) {
//			e.printStackTrace();
//		}
//
//	}

	@Override
	public synchronized Map<String, Object> saveOrUpdate(BizActivityDomain domain) {
		Map<String, Object> retMap = new HashMap<String, Object>();
		try {
			BizActivityDomain paraDomain = new BizActivityDomain();
//			paraDomain.setTitle(domain.getTitle());
			paraDomain.setSid(domain.getSid());
			paraDomain.setCity(domain.getCity());
			paraDomain.setBankId(domain.getBankId());

			BizActivityDomain retAct = bizActivityDao.findOne(parseDomaintoQuery(paraDomain));

			if (null != retAct) {
				paraDomain.setId(retAct.getId());
				update(domain, paraDomain);
				retMap.put(Globals.GLOBAL_SERVICE_RET_ID, retAct.getId());
				retMap.put(Globals.GLOBAL_SERVICE_RET_CODE, Globals.GLOBAL_SERVICE_CODE_EXIST);
				return retMap;
			} else {
				save(domain);
				retMap.put(Globals.GLOBAL_SERVICE_RET_ID, domain.getId());
				retMap.put(Globals.GLOBAL_SERVICE_RET_CODE, Globals.GLOBAL_SERVICE_CODE_NOTEXIST);
				return retMap;
			}
		} catch (Exception e) {
			e.printStackTrace();
			retMap.put(Globals.GLOBAL_SERVICE_RET_CODE, Globals.GLOBAL_SERVICE_CODE_ERROR);
			return retMap;
		}
	}

	@Override
	public synchronized void update(BizActivityDomain domain, BizActivityDomain contition) {
		// handle parse conditon
		Query query = parseDomaintoQuery(contition);
		// handle update condition...
		Update update = parseDomaintoUpdate(domain);
		// update discountWeeks if necessary
		Integer[] disCountWeeks = domain.getDiscountWeek();
		if (disCountWeeks != null && disCountWeeks.length > 0) {
			update.addToSet("discountWeek", BasicDBObjectBuilder.start("$each", disCountWeeks).get());
		}
		// if update is empty will remove the mongo data
		if (update.getUpdateObject().toMap().size() != 0) {
			bizActivityDao.update(query, update);
		}
	}

	@Override
	public BizActivityDomain findOne(BizActivityDomain domain) {
		Query query = parseDomaintoQuery(domain);
		BizActivityDomain retDomain = bizActivityDao.findOne(query);
		return retDomain;
	}

	@Override
	public List<BizActivityDomain> getListByIds(List<Long> ids, BaseQueryOrder order) {
		if (null != ids && ids.size() > 0) {
			Query qry = new Query();
			qry.addCriteria(Criteria.where("_id").in(ids));
			return bizActivityDao.getPageResult(qry, order).getContent();
		}
		return Lists.newArrayList();
	}

}
